﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace InstantSpine.GUI
{
    /// <summary>
    /// Interaction logic for UserControl1.xaml
    /// </summary>
    public partial class LateralMeshViz : UserControl
    {
        public int AxialResolutionVB {
            get { return (int)GetValue(AxialResolutionVBProperty); }
            set { SetValue(AxialResolutionVBProperty, value); }
        }

        // Using a DependencyProperty as the backing store for AxialResolutionVB.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty AxialResolutionVBProperty =
            DependencyProperty.Register("AxialResolutionVB", typeof(int), typeof(LateralMeshViz), new PropertyMetadata(5, OnResolutionPropertyChanged));

        public int AxialResolutionDisc {
            get { return (int)GetValue(AxialResolutionDiscProperty); }
            set { SetValue(AxialResolutionDiscProperty, value); }
        }

        // Using a DependencyProperty as the backing store for AxialResolutionDisc.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty AxialResolutionDiscProperty =
            DependencyProperty.Register("AxialResolutionDisc", typeof(int), typeof(LateralMeshViz), new PropertyMetadata(3, OnResolutionPropertyChanged));

        public SolidColorBrush StrokeColor {
            get { return (SolidColorBrush)GetValue(StrokeColorProperty); }
            set { SetValue(StrokeColorProperty, value); }
        }

        // Using a DependencyProperty as the backing store for StrokeColor.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty StrokeColorProperty =
            DependencyProperty.Register("StrokeColor", typeof(SolidColorBrush), typeof(LateralMeshViz), new PropertyMetadata(Brushes.DarkGray, OnResolutionPropertyChanged));

        public SolidColorBrush OutlineStrokeColor {
            get { return (SolidColorBrush)GetValue(OutlineStrokeColorProperty); }
            set { SetValue(OutlineStrokeColorProperty, value); }
        }

        // Using a DependencyProperty as the backing store for OutlineStrokeColor.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty OutlineStrokeColorProperty =
            DependencyProperty.Register("OutlineStrokeColor", typeof(SolidColorBrush), typeof(LateralMeshViz), new PropertyMetadata(Brushes.Black, OnResolutionPropertyChanged));

        public double StrokeThickness {
            get { return (double)GetValue(StrokeThicknessProperty); }
            set { SetValue(StrokeThicknessProperty, value); }
        }

        // Using a DependencyProperty as the backing store for StrokeThickness.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty StrokeThicknessProperty =
            DependencyProperty.Register("StrokeThickness", typeof(double), typeof(LateralMeshViz), new PropertyMetadata(3.0, OnResolutionPropertyChanged));

        public double OutlineStrokeThickness {
            get { return (double)GetValue(OutlineStrokeThicknessProperty); }
            set { SetValue(OutlineStrokeThicknessProperty, value); }
        }

        // Using a DependencyProperty as the backing store for OutlineStrokeThickness.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty OutlineStrokeThicknessProperty =
            DependencyProperty.Register("OutlineStrokeThickness", typeof(double), typeof(LateralMeshViz), new PropertyMetadata(2.0, OnResolutionPropertyChanged));

        public static void OnResolutionPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs args) {
            var meshResCtrl = d as LateralMeshViz;
            //MessageBox.Show(string.Format("new res = {0}", meshResCtrl.InnerRadialResolution));
            if (meshResCtrl != null) {
                meshResCtrl.RedrawMeshViz();
            }
        }

        private void RedrawMeshViz() {            
            vboutline.StrokeThickness = OutlineStrokeThickness;
            vboutline.Stroke = OutlineStrokeColor;
            discoutline.StrokeThickness = OutlineStrokeThickness;
            discoutline.Stroke = OutlineStrokeColor;

            RefreshAxialMeshViz(vbcanvas, AxialResolutionVB);
            RefreshAxialMeshViz(disccanvas, AxialResolutionDisc);

            var vbtxt = new TextBlock {
                Text = "Vertebra",
                FontFamily = new FontFamily("Segoe UI"),
                FontSize = 13.0,
                FontWeight = FontWeights.Bold,
            };
            vbtxt.RenderTransform = new TranslateTransform(58, 52);
            vbcanvas.Children.Add(vbtxt);

            var txt = new TextBlock { 
                Text = "Disc", 
                FontFamily = new FontFamily("Segoe UI"), 
                FontSize = 13.0, 
                FontWeight = FontWeights.Bold,                
            };
            txt.RenderTransform = new TranslateTransform(75, 15);
            disccanvas.Children.Add(txt);            
        }

        private void RefreshAxialMeshViz(Canvas c, int axialRes) {
            c.Children.Clear();

            for (int i = 1; i < axialRes; ++i) {
                var height = c.Height * (i / (double)axialRes);
                c.Children.Add(new Line {
                    X1 = 0.0,
                    Y1 = height,
                    X2 = c.Width,
                    Y2 = height,
                    Stroke = StrokeColor,
                    StrokeThickness = StrokeThickness
                });
            }
        }

        public LateralMeshViz()
        {
            InitializeComponent();
        }
    }
}
